/*****************************************************************************
  Copyright ?2002-2004 by Martin Cook. All rights are reserved. If you like
  this code then feel free to go ahead and use it. The only thing I ask is 
  that you don't remove or alter my copyright notice. Your use of this 
  software is entirely at your own risk. I make no claims about the 
  reliability or fitness of this code for any particular purpose. If you 
  make changes or additions to this code then please clearly mark your code 
  as yours. If you have questions or comments then please contact me at: 
  martin@codegator.com
  
  Have Fun! :o)
*****************************************************************************/

using System;
using System.Data;
using System.Security.Principal;
using System.Threading;

using CG.Security.Configuration;
using CG.Security.Data;

namespace CG.Security
{

	/// <summary>
	/// Provides static methods that supply helper utilities for managing 
	/// associations between users and rights.
	/// </summary>
	public sealed class UserRightManager
	{
		
		// ******************************************************************
		// Attributes.
		// ******************************************************************

		#region Attributes

		/// <summary>
		/// The data object used to interface with the database.
		/// </summary>
		private static IUserRightData c_userRightData;

		#endregion

		// ******************************************************************
		// Constructors.
		// ******************************************************************

		#region Constructors

		/// <summary>
		/// Class constructor.
		/// </summary>
		static UserRightManager()
		{
			c_userRightData = DataManager.UserRightData;
		} // End UserRightManager()

		#endregion

		// ******************************************************************
		// Public methods.
		// ******************************************************************

		#region Public methods

		/// <summary>
		/// Creates a new association between a user and a right.  Note that 
		/// the calling user must be a member of the 'Admin' role in order to 
		/// perform this action.
		/// </summary>
		/// <param name="userID">The identifier for the user.</param>
		/// <param name="rightID">The identifier for the right.</param>
		/// <param name="enableFlag">A flag that decides whether to add
		/// or remove the specified right from the effective rights list.</param>
		public static void Create(
			int userID,
			int rightID,
			bool enableFlag
			)
		{

			// Check the role of the user before we proceed.
			if (!Thread.CurrentPrincipal.IsInRole("Admin"))
				throw new SecurityException("User must be in the Admin role to perform this action!");

			// Create the association in the database.
			c_userRightData.Create(
				userID,
				rightID,
				enableFlag
				);

		} // End Create()

		// ******************************************************************

		/// <summary>
		/// Deletes an association between a user and a right. Note that 
		/// the calling user must be a member of the 'Admin' role in order to 
		/// perform this action.
		/// </summary>
		/// <param name="userID">The identifier for the user.</param>
		/// <param name="rightID">The identifier for the right.</param>
		public static void Delete(
			int userID,
			int rightID
			)
		{

			// Check the role of the user before we proceed.
			if (!Thread.CurrentPrincipal.IsInRole("Admin"))
				throw new SecurityException("User must be in the Admin role to perform this action!");

			// Delete the association in the database.
			c_userRightData.Delete(
				userID,
				rightID
				);

		} // End Delete()

		// ******************************************************************

		/// <summary>
		/// Updates an association between a user and a right. Note that 
		/// the calling user must be a member of the 'Admin' role in order to 
		/// perform this action.
		/// </summary>
		/// <param name="userID">The identifier for the user.</param>
		/// <param name="rightID">The identifier for the right.</param>
		/// <param name="enableFlag">A flag that decides whether to add
		/// or remove the specified right from the effective rights list.</param>
		public static void Update(
			int userID,
			int rightID,
			bool enableFlag
			)
		{

			// Check the role of the user before we proceed.
			if (!Thread.CurrentPrincipal.IsInRole("Admin"))
				throw new SecurityException("User must be in the Admin role to perform this action!");

			// Update the association in the database.
			c_userRightData.Update(
				userID,
				rightID,
				enableFlag
				);

		} // End Update()

		// ******************************************************************

		/// <summary>
		/// Returns a list of all the users that have been explicitly associated 
		/// with the specified right.
		/// </summary>
		/// <param name="userID">The identifier for the right.</param>
		/// <returns>A DataSet containing all the users that are associated
		/// with the specified right.</returns>
		public static System.Data.DataSet FindByRight(
			int rightID
			)
		{

			// Get the list of associations from the database.
			DataSet ds = c_userRightData.FindByRight(
				rightID
				);

			// Ensure the dataset has a consistant name.
			ds.DataSetName = "UserRightData";

			// Ensure the table has a consistant name.
			ds.Tables[0].TableName = "cg_security_user_right";

			return ds;

		} // End FindByRight()

		// ******************************************************************

		/// <summary>
		/// Returns a list of all the rights that are explicitly associated 
		/// with the specified user. (Note: this list will not include any 
		/// rights granted through a users roles - for that list use the 
		/// SecurityManager.EffectiveRight method.
		/// </summary>
		/// <param name="userID">The identifier for the user.</param>
		/// <returns>A DataSet containing all the rights that are associated
		/// with the specified user.</returns>
		public static System.Data.DataSet FindByUser(
			int userID
			)
		{

			// Get the list of associations from the database.
			DataSet ds = c_userRightData.FindByUser(
				userID
				);

			// Ensure the dataset has a consistant name.
			ds.DataSetName = "UserRightData";

			// Ensure the table has a consistant name.
			ds.Tables[0].TableName = "cg_security_user_right";

			return ds;

		} // End FindByUser()

		#endregion

	} // End clas UserRightManager

} // End namespace CG.Security
